/*****************************************************************************/
/* Domino Operation System GUI Specific Module                               */
/*                                                                           */
/* Copyright (C) 2014 Laszlo Arvai                                           */
/* All rights reserved.                                                      */
/*                                                                           */
/* This software may be modified and distributed under the terms             */
/* of the BSD license.  See the LICENSE file for details.                    */
/*****************************************************************************/

///////////////////////////////////////////////////////////////////////////////
// Includes
#include <guiCommon.h>
#include <krnlResourceFile.h>

///////////////////////////////////////////////////////////////////////////////
// Variables defined in other sources
guiFontInfo g_gui_current_font;
dosByte g_gui_text_align = 0;
guiRect g_gui_clip_rect;

///////////////////////////////////////////////////////////////////////////////
// Set text align
void guiSetTextAlign( dosByte in_align )
{
	g_gui_text_align = in_align;
}

///////////////////////////////////////////////////////////////////////////////
// Set font
void guiSetFont( dosHandle in_font_handle )
{
  dosROMAddress address;

	// get the font address
	address = /*l_font_resource_address + */in_font_handle;
	g_gui_current_font.Type										= dosROMReadByte( address++ );
	g_gui_current_font.Flag										= dosROMReadByte( address++ );
	g_gui_current_font.Width									= dosROMReadByte( address++ );
	g_gui_current_font.Height									= dosROMReadByte( address++ );
	g_gui_current_font.Baseline								= dosROMReadByte( address++ );
	g_gui_current_font.HorizontalCharacterGap	= dosROMReadByte( address++ );
	g_gui_current_font.Minascii								= dosROMReadByte( address++ );
	g_gui_current_font.Maxascii								= dosROMReadByte( address++ );
	g_gui_current_font.DefaultCharacter				= dosROMReadByte( address++ );
	g_gui_current_font.UnicodeCount						= dosROMReadWord( address );
	address				+= sizeof( dosWord );

	g_gui_current_font.AsciiTableAddress = address;
}

///////////////////////////////////////////////////////////////////////////////
// Get text extent
guiSize guiGetTextExtent( dosString in_string )
{
	guiSize size;

	dosROMAddress chardata;
	dosInt16 i;
	dosInt16 len;

	// check font
	size.Width	= 0;
	size.Height	= 0;
	if( g_gui_current_font.AsciiTableAddress == 0 )
		return size;

	// height
	size.Height = g_gui_current_font.Height;

	len = strGetLength( in_string );

	// if the font is fixed
	if( ( g_gui_current_font.Flag & dosGUIFF_FIXED ) != 0 )
	{
		size.Width = g_gui_current_font.Width * len;
	}
	else
	{
		size.Width = 0;
		for( i = 0; i < len; i++ )
		{
			if( in_string[i] >= g_gui_current_font.Minascii && in_string[i] <= g_gui_current_font.Maxascii )
			{
				chardata = dosROMReadWord( (in_string[i] - g_gui_current_font.Minascii) * sizeof( dosWord ) + g_gui_current_font.AsciiTableAddress );
				size.Width += dosROMReadByte( chardata );
			}
		}
	}

	return size;
}

///////////////////////////////////////////////////////////////////////////////
// Get resource text extent
guiSize guiGetResourceTextExtent( dosHandle in_string_handle )
{
	guiSize size;

	dosROMAddress chardata;
	dosInt16 i;
	dosInt16 len;
  dosROMAddress string;
  dosChar ch;

	size.Width = 0;
	size.Height = 0;

  // check handle
  if( in_string_handle == krnlINVALID_HANDLE )
    return size;

	// check font
	size.Width	= 0;
	size.Height	= 0;
	if( g_gui_current_font.AsciiTableAddress == 0 )
		return size;

	// height
	size.Height = g_gui_current_font.Height;

	len = (dosInt16)krnlGetResourceStringLength( in_string_handle );
  string = (dosInt16)krnlGetResourceString( in_string_handle );

	// if the font is fixed
	if( ( g_gui_current_font.Flag & dosGUIFF_FIXED ) != 0 )
	{
		size.Width = g_gui_current_font.Width * len;
	}
	else
	{
		size.Width = 0;
		for( i = 0; i < len; i++ )
		{
      ch = dosROMReadByte( string + i );

			if( ch >= g_gui_current_font.Minascii && ch <= g_gui_current_font.Maxascii )
			{
				chardata = dosROMReadWord( (ch - g_gui_current_font.Minascii) * sizeof( dosWord ) + g_gui_current_font.AsciiTableAddress );
				size.Width += dosROMReadByte( chardata );
			}
		}
	}

	return size;
}

///////////////////////////////////////////////////////////////////////////////
// Get bitmap size
guiSize guiGetBitmapSize( dosHandle in_bitmap_handle )
{
	dosROMAddress resource_address;
	dosInt16 width;
	dosInt16 height;
  guiSize size;

	// get the bitmap address
	resource_address = /*l_bitmap_resource_address + */in_bitmap_handle;

	// get bitmap data
	width = dosROMReadWord( resource_address );
	resource_address += sizeof( dosWord );

	height = dosROMReadWord( resource_address );
	resource_address += sizeof( dosWord );

  // store size
  size.Width = width;
  size.Height = height;

  return size;
}

///////////////////////////////////////////////////////////////////////////////
// Extend rect to include the specified rectangle
void guiExtendRect( guiRect* in_rect_to_extend, const guiRect* in_rect_to_include )
{
  // left
  if( in_rect_to_extend->Left == guiINVALID_COORDINATE )
    in_rect_to_extend->Left = in_rect_to_include->Left;
  else
  {
    if( in_rect_to_include->Left < in_rect_to_extend->Left )
      in_rect_to_extend->Left = in_rect_to_include->Left;
  }

  // top
  if( in_rect_to_extend->Top == guiINVALID_COORDINATE )
    in_rect_to_extend->Top = in_rect_to_include->Top;
  else
  {
    if( in_rect_to_include->Top < in_rect_to_extend->Top )
      in_rect_to_extend->Top = in_rect_to_include->Top;
  }

  // right
  if( in_rect_to_extend->Right == guiINVALID_COORDINATE )
    in_rect_to_extend->Right = in_rect_to_include->Right;
  else
  {
    if( in_rect_to_include->Right > in_rect_to_extend->Right )
      in_rect_to_extend->Right = in_rect_to_include->Right;
  }

  // bottom
  if( in_rect_to_extend->Bottom == guiINVALID_COORDINATE )
    in_rect_to_extend->Bottom = in_rect_to_include->Bottom;
  else
  {
    if( in_rect_to_include->Bottom > in_rect_to_extend->Bottom )
      in_rect_to_extend->Bottom = in_rect_to_include->Bottom;
  }
}
